wayland: Support always-on-top / sticky windows
authorJasper St. Pierre <jstpierre@mecheye.net>
Wed, 9 Oct 2013 20:55:55 +0000 (16:55 -0400)
committerJasper St. Pierre <jstpierre@mecheye.net>
Mon, 28 Oct 2013 22:03:26 +0000 (18:03 -0400)
Use the new gtk-shell APIs available in mutter to add support for this.

https://bugzilla.gnome.org/show_bug.cgi?id=710056

gdk/wayland/gdkdisplay-wayland.c
gdk/wayland/gdkwindow-wayland.c
gdk/wayland/protocol/gtk-shell.xml
gtk/gtkwindow.c

index 71debb944a8854ed3bad412fe2bc37e7325b4283..f90db8ff48e5c60b08cdcfb641f1091726348fc4 100644 (file)
@@ -169,7 +169,7 @@ gdk_registry_handle_global(void *data, struct wl_registry *registry, uint32_t id
        wl_registry_bind(display_wayland->wl_registry, id, &wl_shell_interface, 1);
   } else if (strcmp(interface, "gtk_shell") == 0) {
     display_wayland->gtk_shell =
-      wl_registry_bind(display_wayland->wl_registry, id, &gtk_shell_interface, 1);
+      wl_registry_bind(display_wayland->wl_registry, id, &gtk_shell_interface, 2);
     _gdk_wayland_screen_set_has_gtk_shell (display_wayland->screen);
     /* We need another roundtrip to receive the shell capabilities */
     wait_for_roundtrip(display_wayland);
index 70abf77da5696f993249fb9c4233c31a3afe07b1..e9f2d3bf8a03ec4a1b6d41905ffabdb121e817a6 100644 (file)
@@ -1647,15 +1647,23 @@ gdk_wayland_window_deiconify (GdkWindow *window)
 static void
 gdk_wayland_window_stick (GdkWindow *window)
 {
+  GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+
   if (GDK_WINDOW_DESTROYED (window))
     return;
+
+  gtk_surface_set_on_all_workspaces (impl->gtk_surface, TRUE);
 }
 
 static void
 gdk_wayland_window_unstick (GdkWindow *window)
 {
+  GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+
   if (GDK_WINDOW_DESTROYED (window))
     return;
+
+  gtk_surface_set_on_all_workspaces (impl->gtk_surface, FALSE);
 }
 
 static void
@@ -1769,10 +1777,12 @@ static void
 gdk_wayland_window_set_keep_above (GdkWindow *window,
                                    gboolean   setting)
 {
-  g_return_if_fail (GDK_IS_WINDOW (window));
+  GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
 
   if (GDK_WINDOW_DESTROYED (window))
     return;
+
+  gtk_surface_set_always_on_top (impl->gtk_surface, setting);
 }
 
 static void
index a4e25653f1902a665dca912036378da7e89bff99..4407cb8981d65b8f8162c17cef839894a9e4b10c 100644 (file)
@@ -1,11 +1,11 @@
 <protocol name="gtk">
 
-  <interface name="gtk_shell" version="1">
+  <interface name="gtk_shell" version="2">
     <enum name="capability">
       <entry name="global_app_menu" value="1"/>
       <entry name="global_menu_bar" value="2"/>
     </enum>
-    
+
     <event name="capabilities">
       <arg name="capabilities" type="uint"/>
     </event>
@@ -16,7 +16,7 @@
     </request>
   </interface>
 
-  <interface name="gtk_surface" version="1">
+  <interface name="gtk_surface" version="2">
     <request name="set_dbus_properties">
       <arg name="application_id" type="string" allow-null="true"/>
       <arg name="app_menu_path" type="string" allow-null="true"/>
       <arg name="application_object_path" type="string" allow-null="true"/>
       <arg name="unique_bus_name" type="string" allow-null="true"/>
     </request>
+
+    <request name="set_workspace">
+      <arg name="workspace" type="uint" />
+    </request>
+
+    <event name="workspace_changed">
+      <arg name="new_workspace" type="uint" />
+    </event>
+
+    <enum name="always_on_top_state">
+      <entry name="not_always_on_top" value="0" />
+      <entry name="always_on_top" value="1" />
+    </enum>
+
+    <request name="set_always_on_top">
+      <arg name="always_on_top" type="uint" />
+    </request>
+
+    <enum name="on_all_workspaces">
+      <entry name="not_on_all_workspaces" value="0" />
+      <entry name="on_all_workspaces" value="1" />
+    </enum>
+
+    <request name="set_on_all_workspaces">
+      <arg name="on_all_workspaces" type="uint" />
+    </request>
   </interface>
 
 </protocol>
index 32f5eeedff87031cc4966da636b6a163a0c68b17..fd690d6314b77a514ab9859d7f8f97e5d929624a 100644 (file)
@@ -8119,7 +8119,6 @@ ontop_window_clicked (GtkMenuItem *menuitem,
   gtk_window_set_keep_above (window, !window->priv->above_initially);
 }
 
-#ifdef GDK_WINDOWING_X11
 static void
 stick_window_clicked (GtkMenuItem *menuitem,
                       gpointer     user_data)
@@ -8138,6 +8137,7 @@ unstick_window_clicked (GtkMenuItem *menuitem,
   gtk_window_unstick (window);
 }
 
+#ifdef GDK_WINDOWING_X11
 static void
 workspace_change_clicked (GtkMenuItem *menuitem,
                           gpointer     user_data)
@@ -8205,25 +8205,25 @@ gtk_window_do_popup (GtkWindow      *window,
                     G_CALLBACK (ontop_window_clicked), window);
   gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem);
 
+  menuitem = gtk_check_menu_item_new_with_label (_("Always on Visible Workspace"));
+  gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (menuitem), TRUE);
+  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), priv->stick_initially);
+  gtk_widget_show (menuitem);
+  g_signal_connect (G_OBJECT (menuitem), "activate",
+                    G_CALLBACK (stick_window_clicked), window);
+  gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem);
+
+  menuitem = gtk_check_menu_item_new_with_label (_("Only on This Workspace"));
+  gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (menuitem), TRUE);
+  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), !priv->stick_initially);
+  gtk_widget_show (menuitem);
+  g_signal_connect (G_OBJECT (menuitem), "activate",
+                    G_CALLBACK (unstick_window_clicked), window);
+  gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem);
+
 #ifdef GDK_WINDOWING_X11
   if (GDK_IS_X11_DISPLAY (gtk_widget_get_display (GTK_WIDGET (window))))
     {
-      menuitem = gtk_check_menu_item_new_with_label (_("Always on Visible Workspace"));
-      gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (menuitem), TRUE);
-      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), priv->stick_initially);
-      gtk_widget_show (menuitem);
-      g_signal_connect (G_OBJECT (menuitem), "activate",
-                        G_CALLBACK (stick_window_clicked), window);
-      gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem);
-
-      menuitem = gtk_check_menu_item_new_with_label (_("Only on This Workspace"));
-      gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (menuitem), TRUE);
-      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), !priv->stick_initially);
-      gtk_widget_show (menuitem);
-      g_signal_connect (G_OBJECT (menuitem), "activate",
-                        G_CALLBACK (unstick_window_clicked), window);
-      gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem);
-
       if (!priv->stick_initially)
         {
           guint32 n_desktops, desktop;